﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Activation;
using System.ServiceModel;
using Microsoft.SharePoint;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.IO;

namespace SPRemoteService.SPServer.ISAPI
{
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class RemoteService : IRemoteService
    {
        private static Dictionary<string, string> WinAppInfos = new Dictionary<string, string>();
        private static Dictionary<string, TcpClient> WinAppInfosTcp = new Dictionary<string, TcpClient>();
        private static TcpListener _tcpListener = new TcpListener(10080);
        private static bool _isRunning = false;
        private char _separatorChar = '*';

        private void StartTcpListener()
        {
            if (!_isRunning)
            {
                while (true)
                {
                    _tcpListener.Start();
                    _isRunning = true;
                    TcpClient tcpClient = _tcpListener.AcceptTcpClient();

                    Random rnd = new Random();
                    string AppId = rnd.Next(10000).ToString();
                    WinAppInfosTcp.Add(AppId, tcpClient);
                    StreamWriter writer = new StreamWriter(tcpClient.GetStream());
                    writer.WriteLine(AppId);
                    //make sure all bytes are written
                    writer.Flush();
                    writer = null;
                }
            }
        }

        private WinAppRemoteService.WinAppRemoteServiceClient CreatePort(string endpointUrl)
        {
            BasicHttpBinding binding = new BasicHttpBinding();
            binding.Name = "BasicHttpBinding_IWinAppRemoteService";

            binding.MaxBufferPoolSize = Int32.MaxValue;
            binding.MaxReceivedMessageSize = Int32.MaxValue;
            binding.ReaderQuotas.MaxArrayLength = Int32.MaxValue;
            binding.ReaderQuotas.MaxBytesPerRead = Int32.MaxValue;

            EndpointAddress endpointAddress = new EndpointAddress(endpointUrl);
            WinAppRemoteService.WinAppRemoteServiceClient remoteServiceClient = new WinAppRemoteService.WinAppRemoteServiceClient(binding, endpointAddress);
            return remoteServiceClient;

        }

        public bool ConnectTo(string appId)
        {
            return WinAppInfosTcp.ContainsKey(appId);
        }

        public string Disconnect()
        {
            return "ok";
        }

        public string RegisterApp(string endpointUrl)
        {
            System.Threading.Thread listenerThread = new System.Threading.Thread(new System.Threading.ThreadStart(StartTcpListener));
            listenerThread.Start();
            return "";
            //if (WinAppInfos.Values.Contains(endpointUrl))
            //{
            //    return WinAppInfos.First(x => x.Value == endpointUrl).Key.ToString();                
            //}
            //else
            //{
            //    Uri endpointUri = new Uri(endpointUrl);

            //    //Ping
            //    Ping pingSender = new Ping();
            //    PingOptions options = new PingOptions();

            //    // Use the default Ttl value which is 128, 
            //    // but change the fragmentation behavior.
            //    options.DontFragment = true;

            //    // Create a buffer of 32 bytes of data to be transmitted. 
            //    string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
            //    byte[] buffer = Encoding.ASCII.GetBytes(data);
            //    int timeout = 120;
            //    PingReply reply = pingSender.Send(endpointUri.Host, timeout, buffer, options);
            //    if (reply.Status == IPStatus.Success)
            //    {
            //        Random rnd = new Random();
            //        string AppId = rnd.Next(10000).ToString();
            //        WinAppInfos.Add(AppId, endpointUrl);
            //        return AppId;
            //    }
            //    else
            //    {
            //        return "";
            //    }
            //}
        }

        public void UnRegisterApp(string appId)
        {
            WinAppInfos.Remove(appId);
        }

        public bool OpenFile(string appId, string siteUrl, string fileUrl)
        {
            try
            {
                //string endpointUrl = WinAppInfos[appId];
                //WinAppRemoteService.WinAppRemoteServiceClient remoteServiceClient = CreatePort(endpointUrl);

                //return remoteServiceClient.OpenFile(siteUrl, fileUrl);

                TcpClient tcpClient = WinAppInfosTcp[appId];
                StreamWriter writer = new StreamWriter(tcpClient.GetStream());
                writer.WriteLine("OpenFile" + _separatorChar + siteUrl + _separatorChar + fileUrl);
                //make sure all bytes are written
                writer.Flush();
                writer = null;
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public bool PageUp(string appId)
        {
            //try
            //{
            //    string endpointUrl = WinAppInfos[appId];
            //    WinAppRemoteService.WinAppRemoteServiceClient remoteServiceClient = CreatePort(endpointUrl);

            //    return remoteServiceClient.PageUp();
            //}
            //catch (Exception ex)
            //{
            //    throw ex;
            //}

            try
            {
                TcpClient tcpClient = WinAppInfosTcp[appId];
                StreamWriter writer = new StreamWriter(tcpClient.GetStream());
                writer.WriteLine("PageUp");
                //make sure all bytes are written
                writer.Flush();
                writer = null;
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

        public bool PageDown(string appId)
        {
            //try
            //{
            //    string endpointUrl = WinAppInfos[appId];
            //    WinAppRemoteService.WinAppRemoteServiceClient remoteServiceClient = CreatePort(endpointUrl);

            //    return remoteServiceClient.PageDown();
            //}
            //catch (Exception ex)
            //{
            //    throw ex;
            //}

            try
            {
                TcpClient tcpClient = WinAppInfosTcp[appId];
                StreamWriter writer = new StreamWriter(tcpClient.GetStream());
                writer.WriteLine("PageDown");
                //make sure all bytes are written
                writer.Flush();
                writer = null;
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

        public void CloseFile(string appId)
        {
            //try
            //{
            //    string endpointUrl = WinAppInfos[appId];
            //    WinAppRemoteService.WinAppRemoteServiceClient remoteServiceClient = CreatePort(endpointUrl);

            //    remoteServiceClient.CloseFile();
            //}
            //catch (Exception ex)
            //{
            //    throw ex;
            //}

            try
            {
                TcpClient tcpClient = WinAppInfosTcp[appId];
                StreamWriter writer = new StreamWriter(tcpClient.GetStream());
                writer.WriteLine("CloseFile");
                //make sure all bytes are written
                writer.Flush();
                writer = null;
            }
            catch (Exception ex)
            {
                throw ex;
            }

       }

    }
}
